/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package XML;

import controller.ClientController;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import dto.*;
import java.awt.Color;
import java.awt.Font;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.logging.Level;
import javax.swing.ImageIcon;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Attr;
import org.w3c.dom.Text;
import dto.*;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.List;
import java.util.logging.Logger;
import javax.swing.JFileChooser;

/**
 *
 * @author waelelkholy
 */
public class XmlFile {

    private static Document doc;
    private Element root;
    private Account to, from;
    private String messageBody;
    private Font font;
    private Color color;
    private String XmlFilePath;
    List<Message> all_msseages = new ArrayList<>();

    public  XmlFile() {
        try {
            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
            //docFactory.setValidating(true);
            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
            doc = docBuilder.newDocument();
            //Adding the root element to the doc document
            this.addRootElement(doc, "MyMessages");
        } catch (ParserConfigurationException ex) {
            Logger.getLogger(XmlFile.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public void addRootElement(Document doc, String root_name) {
        //Creating the XML tree
        //create the root element and add it to the document
        root = doc.createElement(root_name);
        doc.appendChild(root);
        ////////////////////////////////////////////////
//         StringWriter writer = new StringWriter();
//                writer.write("<?xml version='1.0'?>");
//                writer.write("\n");
//                writer.write("<?xml-stylesheet type='text/xsl' href='parsing.xsl'?>");
//                writer.write("\n");
        ///////////////////////////////////////////////////
        
        //create a comment and put it in the root element 
       Comment comment = doc.createComment("this file is created to save the messages flow of user");
        root.appendChild(comment);
    }

    public void set_message(Message msg)
    {
        this.all_msseages.add(msg);    
    }
   
    
    public void WriteMessage(dto.Message m) 
    {
        //this code is used to generate the elements of every message in anew tree branch
        //create child element, add an attribute, and add to root
        Element child = doc.createElement("message");

        try {
            Attr sender = doc.createAttribute("Sender");
            sender.setValue(m.getFrom().getFirstName().toString() + " :");
            child.setAttributeNode(sender);
        } catch (NullPointerException npex) {
            System.out.println("no account");
        }

        if (m.getBody() != null) {
            try {
                //adding font elements 
                //add a font size attribute to the child
                Element fontSize = doc.createElement("font_size");
                fontSize.setTextContent(String.valueOf(m.getFont().getSize()));
                child.appendChild(fontSize);
                 
               //add a font size attribute to the child
                Element fontName = doc.createElement("font_name");
                fontName.setTextContent(String.valueOf(m.getFont().getName()));
                child.appendChild(fontName);
               //add a font size attribute to the child
                Element fontStyle = doc.createElement("font_style");
                fontStyle.setTextContent(get_font_style(m.getFont()));
                child.appendChild(fontStyle);


                //add a font color attribute to the child but as element
                Element color = doc.createElement("color");
                child.appendChild(color);


                //add vlues of red-green-blue as int values
                Attr red = doc.createAttribute("Red");
                red.setValue(String.valueOf(m.getColor().getRed()));
                color.setAttributeNode(red);
                Attr green = doc.createAttribute("Green");
                green.setValue(String.valueOf(m.getColor().getGreen()));
                color.setAttributeNode(green);
                Attr blue = doc.createAttribute("Blue");
                blue.setValue(String.valueOf(m.getColor().getBlue()));
                color.setAttributeNode(blue);
              //  Element rgb = doc.createElement("rgb");
                Text tt=doc.createTextNode(get_color_name(m.getColor()));
                color.appendChild(tt);
                

                Element body = doc.createElement("body");
                Text text = doc.createTextNode(m.getBody());
                body.appendChild(text);
                // body.setNodeValue("i am wael elkholy...who u are??");
                child.appendChild(body);
            } catch (NullPointerException ex) {
                System.out.println("message object has no text message");
            }
        }

        try {
            //Add the emotion image
            if (!m.getImage().toString().isEmpty()) {
                Element image = doc.createElement("image");
                child.appendChild(image);
                Text image_byte = doc.createTextNode(m.getImage().toString());
                image.appendChild(image_byte);
            }
        } catch (NullPointerException null_image) {
            System.out.println("imageioexeption");
        }
        //adding the childs to the tree
        root.appendChild(child);


    }
    
    /*
     * this method is to iterate through the list of all messages and write it as xml file format
     */
    public void WriteAllMessages(List<Message> allmessages)
    {
      allmessages=this.all_msseages;
        for (Message mess :allmessages)
      {
        WriteMessage(mess);
      }
    }
    public List<Message> get_all_messages( )
    {
     return this.all_msseages; 
    }
    public void saveToFile() {
        try {
            // write the content into xml file
    
            
            JFileChooser chooser=new JFileChooser(".");
            chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            ExtensionFileFilter filter1 = new ExtensionFileFilter("XML OR HTML", new String[] {".xml",".html"});
            chooser.setFileFilter(filter1);
            int option = chooser.showSaveDialog(chooser);  
            if(option == JFileChooser.APPROVE_OPTION)
            {  
              if(chooser.getSelectedFile()!=null){  
             File theFileToSave = chooser.getSelectedFile();
             chooser.setName(messageBody);
//            String path = "E://Chatting//ChatClient//src//xml_messages//";
//            Date dt = new Date();
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            this.WriteAllMessages(this.all_msseages);
            DOMSource source = new DOMSource(doc);
           // String fleName = String.valueOf(dt.getTime()) + ".xml";
           // StreamResult result = new StreamResult(new File(path + fleName));
             StreamResult result = new StreamResult(theFileToSave);
            transformer.transform(source, result);
            this.XmlFilePath = theFileToSave.getName();
            this.write_xslt(theFileToSave);
            this.save_xslt_file(chooser.getSelectedFile().getParent()+"/parsing.xsl");
            System.out.println("File saved!");
            }
        }
        } catch (TransformerException ex) {
            Logger.getLogger(XmlFile.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    private String readFile( String file ) throws IOException {
    BufferedReader reader = new BufferedReader( new FileReader (file));
    String line = null;
    StringBuilder  stringBuilder = new StringBuilder();
    String ls = System.getProperty("line.separator");

    while( ( line = reader.readLine() ) != null ) {
        stringBuilder.append( line );
        stringBuilder.append( ls );
    }

    return stringBuilder.toString();
}
   public void write_xslt(File xmlfile)
   {
    try {
                        File file = new File(xmlfile.getAbsolutePath());
                        String output=readFile(xmlfile.getAbsolutePath());
                        String firstpart=output.substring(0,54);
                       // System.out.println(output.indexOf("mymess"));
                        String second="<?xml-stylesheet type=\""+"text/xsl\""+" href=\""+"parsing.xsl\" "+"?>";
                        String third=output.substring(54,output.length());
                        output="";
                        output=output.concat(firstpart).concat(second).concat(third);
                        // ("?>","<?xml-stylesheet type=\""+"text/xsl\""+" href=\""+"parsing.xsl\" "+"?>");
                        BufferedWriter wr = new BufferedWriter(new FileWriter(file));
                        FileWriter fw = new FileWriter(file);
                        wr.write(output);
                        wr.flush();
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
   
   }
    String get_filepath() {
        return XmlFilePath;
    }
    
    public void save_xslt_file(String path)
    {
     File xslt=new File("src/xsl parser/parsing.xsl");
     File new_file=new File(path);
     BufferedOutputStream out=null;  
      //FileOutputStream fos=null;
  
     try {
       
           out =new BufferedOutputStream(new FileOutputStream(new_file));
        } catch (FileNotFoundException ex) {
            Logger.getLogger(XmlFile.class.getName()).log(Level.SEVERE, null, ex);
        }
     BufferedInputStream input=null;
        try {
              input =new BufferedInputStream(new FileInputStream(xslt));
        } catch (FileNotFoundException ex) {
            Logger.getLogger(XmlFile.class.getName()).log(Level.SEVERE, null, ex);
        }
        
    int byte_;
        try {
            while ((byte_ = input.read()) != -1)
                    out.write(byte_);
                } catch (IOException ex) {
                    Logger.getLogger(XmlFile.class.getName()).log(Level.SEVERE, null, ex);
                };
        try {
            out.flush();
            out.close();
            input.close();
                    
        } catch (IOException ex) {
            Logger.getLogger(XmlFile.class.getName()).log(Level.SEVERE, null, ex);
        }
  }
    
  public String get_color_name(Color c)
  {
        if (Color.BLACK.equals(c)) {
          // the color is black...
          return "black";
      }
      if (Color.GRAY.equals(c)) {
          // the color is black...
          return "GRAY";
      }
      if (Color.BLUE.equals(c)) {
          // the color is black...
          return "BLUE";
      }
      if (Color.GREEN.equals(c)) {
          // the color is black...
          return "GREEN";
      }

      if (Color.MAGENTA.equals(c)) {
          // the color is black...
          return "MAGENTA";
      }
      if (Color.RED.equals(c)) {
          // the color is black...
          return "RED";
      }

      if (Color.ORANGE.equals(c)) {
          // the color is black...
          return "ORANGE";
      }

      if (Color.YELLOW.equals(c)) {
          // the color is black...
          return "YELLOW";
      }
      return "Black";

  }
  
  public String get_font_style(Font f)
  {
  if(f.getStyle()==1)
     return "BOLD";
  else if(f.getStyle()==2)
    return "Italic";
  else return "Normal";
      }
    public static void main(String[] args) {
        XmlFile xmlfile = new XmlFile();
        for(int i=0;i<4;i++)
        {
        Account acc = new Account();
        acc.setFirstName("wael"+i);
        acc.setLastName("elkholy"+i);
       
        dto.Message dto = new dto.Message();
        dto.setFrom(acc);
        dto.setColor(Color.YELLOW);
        dto.setBody("wael is zml");
        ImageIcon im = new ImageIcon("src/resources/mail-blue-icon.png");
        dto.setImage(im);
       // System.out.println(Color.yellow.getRGB());
        Font fontt=new Font("SANS_SERIF",0, 30);
        dto.setFont(fontt);
        xmlfile.set_message(dto);
     }
        
        xmlfile.saveToFile();
        xmlfile.save_xslt_file("ddd");
   }
}
